package io.gitee.zhangbinhub.admin.service

import com.mybatisflex.core.query.QueryChain
import com.mybatisflex.core.query.QueryWrapper
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.base.OauthBaseService
import io.gitee.zhangbinhub.admin.entity.RuntimeConfig
import io.gitee.zhangbinhub.admin.mapper.RuntimeConfigMapper
import io.gitee.zhangbinhub.admin.po.RuntimePo
import io.gitee.zhangbinhub.admin.po.RuntimeQueryPo
import io.gitee.zhangbinhub.admin.repo.RuntimeConfigRepository
import io.gitee.zhangbinhub.admin.repo.UserRepository
import io.gitee.zhangbinhub.admin.vo.CustomerQueryPageVo
import io.gitee.zhangbinhub.admin.vo.RuntimeConfigVo
import org.noear.solon.annotation.Component
import org.noear.solon.annotation.Inject
import org.noear.solon.data.annotation.Transaction
import java.util.concurrent.ConcurrentHashMap

@Component
open class RuntimeConfigService(
    @Inject userRepository: UserRepository,
    private val runtimeConfigRepository: RuntimeConfigRepository
) : OauthBaseService(userRepository) {

    private val runtimeConfigConcurrentHashMap = ConcurrentHashMap<String, RuntimeConfig>()

    fun loadRuntimeConfig() {
        synchronized(this) {
            runtimeConfigConcurrentHashMap.clear()
            runtimeConfigRepository.selectAll()
                .forEach { runtimeConfig -> runtimeConfigConcurrentHashMap[runtimeConfig.name] = runtimeConfig }
        }
    }

    fun findAll(): Map<String, RuntimeConfigVo> = runtimeConfigConcurrentHashMap.mapValues { entry ->
        RuntimeConfigMapper.INSTANCE.entityToVo(entry.value)
    }

    fun findByName(name: String): RuntimeConfig? = runtimeConfigConcurrentHashMap[name]

    @Transaction
    @Throws(WebException::class)
    open fun doCreate(runtimePo: RuntimePo): RuntimeConfig =
        runtimeConfigRepository.selectOneByQuery(QueryWrapper.create().where(RuntimeConfig::name).eq(runtimePo.name!!))
            .let {
                if (it != null) {
                    throw WebException("参数信息已存在")
                } else {
                    RuntimeConfig(
                        name = runtimePo.name!!,
                        value = runtimePo.value,
                        configDes = runtimePo.configDes,
                        enabled = runtimePo.enabled ?: true,
                        covert = true
                    ).apply {
                        runtimeConfigRepository.insert(this)
                    }
                }
            }

    @Transaction
    @Throws(WebException::class)
    open fun doUpdate(runtimePo: RuntimePo): RuntimeConfig =
        runtimeConfigRepository.selectOneById(runtimePo.id!!).apply {
            value = runtimePo.value
            enabled = runtimePo.enabled ?: true
            configDes = runtimePo.configDes
        }.also { runtimeConfigRepository.update(it, false) }

    @Transaction
    open fun doDelete(idList: MutableList<String>) = runtimeConfigRepository.deleteByQuery(
        QueryWrapper.create().where(RuntimeConfig::id).`in`(idList).and(RuntimeConfig::covert).eq(true)
    )

    fun doQuery(runtimeQueryPo: RuntimeQueryPo): CustomerQueryPageVo<RuntimeConfig> =
        QueryChain.of(runtimeConfigRepository)
            .where(RuntimeConfig::name).like(runtimeQueryPo.name, !CommonTools.isNullStr(runtimeQueryPo.name))
            .and(RuntimeConfig::value).like(runtimeQueryPo.value, !CommonTools.isNullStr(runtimeQueryPo.value))
            .and(RuntimeConfig::enabled).eq(runtimeQueryPo.enabled, runtimeQueryPo.enabled != null)
            .let { queryChain ->
                doPageQuery(runtimeQueryPo.queryParam!!, queryChain)
            }
}
